package org.example.util;


import com.example.fanqie.entity.Novel;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.*;

import org.apache.lucene.index.DirectoryReader;

import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.search.*;

import org.apache.lucene.queryparser.classic.QueryParser;

import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.IOException;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;



//lucene索引器工具类
@Component

public class LuceneIndexerutil {

    private Directory indexDirectory;
    private Analyzer analyzer;




    public LuceneIndexerutil ( @Value("${spring.indexDir.path}") String indexDir) throws IOException {
        indexDirectory = FSDirectory.open(Paths.get(indexDir));
        analyzer = new StandardAnalyzer();
    }


    //
    public void indexNovel(List<Novel> novels) {
        IndexWriterConfig config = new IndexWriterConfig(analyzer);

        // 使用同一个IndexWriter实例来删除旧索引并添加新索引
        try (IndexWriter writer = new IndexWriter(indexDirectory, config)) {
            // 删除所有旧文档
            writer.deleteAll();

            // 遍历Novel列表并索引每个Novel
            for (Novel novel : novels) {
                Document doc = new Document();
                // 使用TextField进行全文搜索
                doc.add(new TextField("title", novel.getTitle(), Field.Store.YES));
                doc.add(new TextField("categoryName", novel.getCategoryName(), Field.Store.YES));
                doc.add(new StoredField("wordCount", String.valueOf(novel.getWordCount())));
                doc.add(new StoredField("coverImage", novel.getCoverImage()));
                doc.add(new StoredField("chapterTitle", String.valueOf(novel.getChapterTitle())));
                doc.add(new StoredField("publishDatezuixin", String.valueOf(novel.getPublishDatezuixin())));
                doc.add(new StoredField("statu", novel.getStatu()));
                doc.add(new StoredField("novelId", novel.getNovelId()));

                // 如果authorName不需要全文搜索，可以使用StringField
                doc.add(new TextField("authorName", novel.getAuthorName(), Field.Store.YES));
                // 使用TextField进行全文搜索
                doc.add(new TextField("introduction", novel.getIntroduction(), Field.Store.YES));

                // 将Document添加到索引中
                writer.addDocument(doc);


            }

            // 可选：优化索引（这通常不是必需的，因为IndexWriter在关闭时会自动进行合并）
            // 但如果您想立即释放内存或磁盘空间，可以调用它
            // writer.forceMerge(1); // 强制合并索引为一个单独的段
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    @Resource
    private RedisCacheUtil redisCacheUtil;


    // 省略其他代码

    public List<Novel> searchNovel(String queryString)  {
        List<Novel> results = new ArrayList<>();
        Query query = null; // 初始化 query 变量，以便在 if-else 结构外部可访问
        try (IndexReader reader = DirectoryReader.open(indexDirectory)) {
            IndexSearcher searcher = new IndexSearcher(reader);

            // 检查查询字符串是否为空或仅包含空格
            if (queryString == null || queryString.trim().isEmpty()) {
                // 创建一个匹配所有文档的查询
                query = new MatchAllDocsQuery();
            } else {
                // 使用 MultiFieldQueryParser 解析查询字符串
                QueryParser parser = new MultiFieldQueryParser(new String[]{"title", "authorName", "introduction"}, analyzer);
                query = parser.parse(queryString);
            }

            if (query != null) { // 确保 query 不是 null
                TopDocs topDocs = searcher.search(query, 10); // 获取前10个结果

                for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
                    Document doc = searcher.doc(scoreDoc.doc);
                    Novel novel = new Novel();
                    novel.setTitle(doc.get("title"));
                    novel.setAuthorName(doc.get("authorName"));
                    novel.setIntroduction(doc.get("introduction"));
                    novel.setWordCount(Integer.parseInt(doc.get("wordCount")));
                    novel.setCategoryName(doc.get("categoryName"));
                    novel.setCoverImage(doc.get("coverImage"));
                    novel.setChapterTitle(doc.get("chapterTitle"));
                    novel.setPublishDatezuixin(LocalDate.parse(doc.get("publishDatezuixin")));
                    novel.setStatu(Integer.valueOf(doc.get("statu")));
                    novel.setNovelId(Integer.valueOf(doc.get("novelId")));
                    results.add(novel);
                }
            }
        } catch (ParseException | IOException e) {
            throw new RuntimeException("Failed to parse query: " + queryString, e);
        }

        return results;
    }
}
